package net.yambal.android.air.roulette
{
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.events.TouchEvent;
	import flash.utils.Timer;
	
	import mx.core.UIComponent;
	import mx.events.CollectionEvent;
	import mx.events.FlexEvent;
	
	import net.yambal.android.air.roulette.manager.RouletteManager;
	
	import spark.components.Button;
	
	public class RouletteCircle extends UIComponent
	{
		private var _mng:RouletteManager = null;
		
		private var _isCreationCompleted:Boolean = false;
		private var _center_button:RouletteCenterButton = null;
		private var _list:Array = null;
		private var _peace_wrapper:UIComponent = null;
		
		public function RouletteCircle()
		{
			super();
			_mng = RouletteManager.getInstance();
			_mng.items.addEventListener(CollectionEvent.COLLECTION_CHANGE, onListChange);
			
			addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComlete);
		}
		
		private function onCreationComlete(e:FlexEvent):void{
			trace(this + ":onCreationComlete");
			_isCreationCompleted = true;
			list = _mng.items.toArray();
			
			draw();
		}
		
		private function onListChange(e:CollectionEvent):void{
			trace("onListChange");
			list = _mng.items.toArray();
		}
		
		public function set list(arr:Array):void{
			trace("list:" + arr);
			_list = arr;

			draw();
		}
		
		/**
		 * 描画する
		 **/
		private function draw():void{
			trace("draw");
			
			// 全て消去
			while(numChildren > 0){
				trace("\tremove");
				removeChildAt(0);
			}
			
			// 描画できないならしない
			if(!_isCreationCompleted || _list == null || _list.length < 0){
				trace("\tescape");
				return;
			}

			// RoulettePeaceを配置
			_peace_wrapper = new UIComponent();
			var degree:Number = 360 / _list.length;
			for(var i:int = 0; i < _list.length; i++){
				trace("\tdraw:" + _list[i]);
				var p:RoulettePeace = new RoulettePeace();
				p.degree = degree;
				p.roulette_item = _list[i];
				p.setRotation(degree * i);
				
				p.x = 100;
				p.y = 100;
				
				_peace_wrapper.addChild(p);
			}
			addChild(_peace_wrapper);
			
			_center_button = new RouletteCenterButton();
			_center_button.x = 100;
			_center_button.y = 100;
			addChild(_center_button);
			
			_center_button.addEventListener(MouseEvent.CLICK, onTap);
			_center_button.addEventListener(TouchEvent.TOUCH_TAP, onTap);
			
			callLater(onDraw);
			
		}
		
		private function onDraw():void{
			resetGrow();
			//startTurn();
		}
		
		private function onTap(e:Event):void{
			if(!_is_turning){
				startTurn();
			}else{
				stopTurn();
			}
		}
		
		// start ---------------------------------------------------
		private var _is_turning:Boolean = false;
		private var _is_stopping:Boolean = false;

		/**
		 * 回転を開始する
		 **/
		public function startTurn():void{
			if(!_is_turning && !_is_stopping){
				trace("start");
	
				// 各変数をリセット
				_is_turning = true;
				_is_stopping = false;
				resetGrow();
				
				// Framerate計測を開始
				startMeasureFrameRate();
				
				// 一応、stop中の場合も考慮
				stopDelayTimer();
				
				turn();
			}else{
				trace("回っているか停止行程中に回転開始");
			}
		}
		
		private function turn():void{
			callLater(growNextCL);
		}
		
		private function growNextCL():void{
			growNext();
			
			// Frame描画したことを通知
			addFrame();
			
			if(_is_turning){
				callLater(turn);
			}
		}

		// stop ---------------------------------------------------
		/**
		 * 止める
		 **/
		public function stopTurn():void{
			if(_is_turning && !_is_stopping){
				
				// 各変数をリセット
				_is_turning = false;
				_is_stopping = true;
				
				// Framerateを取得して、ディレイとする
				resetDelayTimer(getFrameRate());
				
				stop();
			}else{
				trace("回っていないか停止行程中に停止");
			}
		}
		
		private function stop():void{
			trace("frowNextForStop:" + _stop_delay);
			stopDelayTimer();
			
			// stop中に再度回りだしたケース
			if(_is_turning){
				return;
			}
			
			// 止まった判定
			if(_stop_delay > 1000){
				onStop();
				return;
			}
			
			growNext();

			startDelayTimer();
		}
		
		private function onDelayTimer(e:TimerEvent):void{
			stopDelayTimer();
			stop();// 繰り返し
		}
		
		/**
		 * 止まった
		 **/
		private function onStop():void{
			_is_stopping = false;
			trace("onStop");
		}
		
		// DelayTimer -----------------------------------------------------
		/**
		 * 加速度的に長くなるDelay（間隔）タイマー
		 * 終了したらonDelayTimer
		 **/
		private var _delay_timer:Timer = null;
		private var _stop_delay:Number = 0;
		private var _step_delay_add:Number = 1;
		
		/**
		 * Delayを初期化する
		 * Stop過程で一度だけセットする
		 **/
		private function resetDelayTimer(init_delay:Number):void{
			stopDelayTimer();
			_stop_delay = init_delay;
			_step_delay_add = 1;
		}
		
		/**
		 * Delayを開始する
		 * Delayは加速度的に長くなる
		 **/
		private function startDelayTimer():void{
			stopDelayTimer();
			
			_stop_delay = _stop_delay + _step_delay_add;
			_step_delay_add ++;
			
			_delay_timer = new Timer(_stop_delay);
			_delay_timer.addEventListener(TimerEvent.TIMER, onDelayTimer);
			_delay_timer.start();
		}

		/**
		 * Delayで使用しているTimerを止める
		 **/
		private function stopDelayTimer():void{
			if(_delay_timer != null){
				_delay_timer.removeEventListener(TimerEvent.TIMER, onDelayTimer);
				_delay_timer.stop();
				_delay_timer.reset();
				_delay_timer = null;
			}
		}

		// 汎用 ------------------------------------------------------------------------
		private var _focused_num:int = -1;
		
		private function resetGrow():void{
			_focused_num = -1;
			for(var i:int = 0; i < _peace_wrapper.numChildren; i++){
				var p:RoulettePeace = _peace_wrapper.getChildAt(i) as RoulettePeace;
				p.grow = false;
			}
		}
		
		private function growNext():void{
			var befor_focus_num:int = _focused_num;
			_focused_num ++;
			_focused_num = _focused_num % (_list.length);
			
			if(befor_focus_num >= 0){
				var befor_p:RoulettePeace = _peace_wrapper.getChildAt(befor_focus_num) as RoulettePeace;
				befor_p.grow = false;
			}
			
			var next_p:RoulettePeace = _peace_wrapper.getChildAt(_focused_num) as RoulettePeace;
			next_p.grow = true;
		}
		
		private function get time_stump():Number{
			var now:Date = new Date();
			return Date.UTC(now.fullYear, now.month, now.date, now.hours, now.minutes, now.seconds, now.milliseconds);;
		}
		
		// Framerate 計測　--------------------------------------------------------------
		private var _startTime:Number = 0;
		private var _grow_counter:Number = 0;
		
		private function startMeasureFrameRate():void{
			_startTime = time_stump;
			_grow_counter = 0;
		}
		
		private function addFrame():void{
			_grow_counter++;
		}
		
		private function getFrameRate():Number{
			return Math.round((time_stump - _startTime) / _grow_counter);
		}
	}
}